#ifndef __M_CONSUMER_H__
#define __M_CONSUMER_H__
#include "../mqcommon/mq_logger.hpp"
#include "../mqcommon/mq_helper.hpp"
#include "../mqcommon/mq_msg.pb.h"   
#include <iostream>
#include <unordered_map> 
#include <mutex>         
#include <memory>        
#include <vector>       
#include <functional>   

namespace zdfmq
{

    // ====================== 1. 消费者回调类型定义 ======================
    /**
     * 消费者回调函数类型：
     * 参数说明：
     * - 第一个 string：队列名称
     * - BasicProperties*：消息属性（Protobuf 结构）
     * - 第二个 string：消息体内容
     */
    using ConsumerCallback = std::function<void(const std::string, const BasicProperties *bp, const std::string)>;

    // ====================== 2. 消费者模型（Consumer） ======================
    struct Consumer
    {
        using ptr = std::shared_ptr<Consumer>; // 智能指针别名

        std::string tag;           // 消费者唯一标识（用于区分不同消费者）
        std::string qname;         // 消费者订阅的队列名称
        bool auto_ack;             // 是否自动确认消息（true：消费后自动删除；false：需手动确认）
        ConsumerCallback callback; // 消息到达时的回调函数

        // 无参构造（主要用于默认初始化）
        Consumer()
        {
            DLOG("new Consumer: %p", this); // 日志：跟踪对象创建
        }

        // 带参构造（实际使用的构造方式）
        Consumer(const std::string &ctag, const std::string &queue_name, bool ack_flag, const ConsumerCallback &cb)
            : tag(ctag), qname(queue_name), auto_ack(ack_flag), callback(std::move(cb))
        {
            DLOG("new Consumer: %p", this); // 日志：跟踪对象创建
        }

        // 析构函数（跟踪对象销毁）
        ~Consumer()
        {
            DLOG("del Consumer: %p", this); // 日志：跟踪对象销毁
        }
    };

    // ====================== 3. 队列消费者管理器（QueueConsumer） ======================
    /**
     * 单个队列的消费者管理器：
     * 功能：
     *  - 管理某个队列的所有消费者
     *  - 支持新增、删除、轮询选择消费者
     *  - 保证线程安全
     */
    class QueueConsumer
    {
    public:
        using ptr = std::shared_ptr<QueueConsumer>; // 智能指针别名

        // 构造函数：初始化队列消费者管理器
        QueueConsumer(const std::string &qname) : _qname(qname), _rr_seq(0) {}

        // 新增消费者（线程安全）
        Consumer::ptr create(const std::string &ctag, const std::string &queue_name, bool ack_flag, const ConsumerCallback &cb)
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全

            // 检查消费者标识是否重复
            for (const auto &consumer : _consumers)
            {
                if (consumer->tag == ctag)
                {
                    return Consumer::ptr(); // 重复则返回空指针
                }
            }

            // 创建新消费者并加入管理
            auto consumer = std::make_shared<Consumer>(ctag, queue_name, ack_flag, cb);
            _consumers.push_back(consumer);
            return consumer;
        }

        // 删除消费者（线程安全）
        void remove(const std::string &ctag)
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全

            // 遍历查找并删除目标消费者
            for (auto it = _consumers.begin(); it != _consumers.end(); ++it)
            {
                if ((*it)->tag == ctag)
                {
                    _consumers.erase(it);
                    return;
                }
            }
        }

        // 轮询选择消费者（线程安全）：采用 RR（Round-Robin）算法
        Consumer::ptr choose()
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全

            if (_consumers.empty())
            {
                return Consumer::ptr(); // 无消费者则返回空指针
            }

            // 计算当前轮询下标
            int idx = _rr_seq % _consumers.size();
            _rr_seq++; // 轮询序号递增
            return _consumers[idx];
        }

        // 检查是否有消费者（线程安全）
        bool empty()
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全
            return _consumers.empty();
        }

        // 检查消费者是否存在（线程安全）
        bool exists(const std::string &ctag)
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全

            for (const auto &consumer : _consumers)
            {
                if (consumer->tag == ctag)
                {
                    return true;
                }
            }
            return false;
        }

        // 清理所有消费者（线程安全）
        void clear()
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全
            _consumers.clear();
            _rr_seq = 0; // 重置轮询序号
        }

    private:
        std::string _qname;                    // 队列名称（标识当前管理器所属队列）
        std::mutex _mutex;                     // 互斥锁（保证线程安全）
        uint64_t _rr_seq;                      // 轮询序号（实现 RR 算法）
        std::vector<Consumer::ptr> _consumers; // 消费者列表（存储当前队列的所有消费者）
    };

    // ====================== 4. 全局消费者管理器（ConsumerManager） ======================
    /**
     * 全局消费者管理器：
     * 功能：
     *  - 管理所有队列的消费者管理器（QueueConsumer）
     *  - 提供队列级别的消费者操作入口（新增、删除、选择等）
     *  - 保证线程安全
     */
    class ConsumerManager
    {
    public:
        using ptr = std::shared_ptr<ConsumerManager>; // 智能指针别名

        // 构造函数：默认初始化
        ConsumerManager() {}

        // 初始化队列的消费者管理器（线程安全）
        void initQueueConsumer(const std::string &qname)
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全

            // 检查队列是否已存在消费者管理器
            if (_qconsumers.find(qname) != _qconsumers.end())
            {
                return; // 已存在则直接返回
            }

            // 创建新的队列消费者管理器并加入管理
            auto qconsumers = std::make_shared<QueueConsumer>(qname);
            _qconsumers.insert({qname, qconsumers});
        }

        // 销毁队列的消费者管理器（线程安全）
        void destroyQueueConsumer(const std::string &qname)
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全
            _qconsumers.erase(qname);                  // 直接删除队列对应的管理器
        }

        // 新增消费者（线程安全）：先找到队列的管理器，再创建消费者
        Consumer::ptr create(const std::string &ctag, const std::string &queue_name, bool ack_flag, const ConsumerCallback &cb)
        {
            QueueConsumer::ptr qcp;

            {
                std::unique_lock<std::mutex> lock(_mutex); // 作用域锁：缩小锁范围
                auto it = _qconsumers.find(queue_name);
                if (it == _qconsumers.end())
                {
                    DLOG("没有找到队列 %s 的消费者管理句柄！", queue_name.c_str());
                    return Consumer::ptr(); // 队列不存在则返回空指针
                }
                qcp = it->second;
            }

            // 调用队列管理器的 create 方法
            return qcp->create(ctag, queue_name, ack_flag, cb);
        }

        // 删除消费者（线程安全）：先找到队列的管理器，再删除消费者
        void remove(const std::string &ctag, const std::string &queue_name)
        {
            QueueConsumer::ptr qcp;

            {
                std::unique_lock<std::mutex> lock(_mutex); // 作用域锁：缩小锁范围
                auto it = _qconsumers.find(queue_name);
                if (it == _qconsumers.end())
                {
                    DLOG("没有找到队列 %s 的消费者管理句柄！", queue_name.c_str());
                    return; // 队列不存在则直接返回
                }
                qcp = it->second;
            }

            // 调用队列管理器的 remove 方法
            qcp->remove(ctag);
        }

        // 轮询选择消费者（线程安全）：先找到队列的管理器，再选择消费者
        Consumer::ptr choose(const std::string &queue_name)
        {
            QueueConsumer::ptr qcp;

            {
                std::unique_lock<std::mutex> lock(_mutex); // 作用域锁：缩小锁范围
                auto it = _qconsumers.find(queue_name);
                if (it == _qconsumers.end())
                {
                    DLOG("没有找到队列 %s 的消费者管理句柄！", queue_name.c_str());
                    return Consumer::ptr(); // 队列不存在则返回空指针
                }
                qcp = it->second;
            }

            // 调用队列管理器的 choose 方法
            return qcp->choose();
        }

        // 检查队列是否有消费者（线程安全）：先找到队列的管理器，再检查
        bool empty(const std::string &queue_name)
        {
            QueueConsumer::ptr qcp;

            {
                std::unique_lock<std::mutex> lock(_mutex); // 作用域锁：缩小锁范围
                auto it = _qconsumers.find(queue_name);
                if (it == _qconsumers.end())
                {
                    DLOG("没有找到队列 %s 的消费者管理句柄！", queue_name.c_str());
                    return false; // 队列不存在则返回 false
                }
                qcp = it->second;
            }

            // 调用队列管理器的 empty 方法
            return qcp->empty();
        }

        // 检查消费者是否存在（线程安全）：先找到队列的管理器，再检查
        bool exists(const std::string &ctag, const std::string &queue_name)
        {
            QueueConsumer::ptr qcp;

            {
                std::unique_lock<std::mutex> lock(_mutex); // 作用域锁：缩小锁范围
                auto it = _qconsumers.find(queue_name);
                if (it == _qconsumers.end())
                {
                    DLOG("没有找到队列 %s 的消费者管理句柄！", queue_name.c_str());
                    return false; // 队列不存在则返回 false
                }
                qcp = it->second;
            }

            // 调用队列管理器的 exists 方法
            return qcp->exists(ctag);
        }

        // 清理所有消费者管理器（线程安全）
        void clear()
        {
            std::unique_lock<std::mutex> lock(_mutex); // 加锁保证线程安全
            _qconsumers.clear();                       // 直接清空所有队列的管理器
        }

    private:
        std::mutex _mutex; // 互斥锁（保证线程安全）
        // 队列名称 → 队列消费者管理器的映射（存储所有队列的消费者管理实例）
        std::unordered_map<std::string, QueueConsumer::ptr> _qconsumers;
    };

} // namespace zdfmq

#endif // __M_CONSUMER_H__